
///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2009, Adam Kubach
//  All rights reserved.
//  BSD License: http://www.opensource.org/licenses/bsd-license.html
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
//
//  Class that contains elevation data.
//
///////////////////////////////////////////////////////////////////////////////

#include "Minerva/Core/ElevationData.h"

#include <limits>

using namespace Minerva::Core;

namespace Detail
{
  const ElevationData::ValueType DEFAULT_NO_DATA_VALUE ( -std::numeric_limits<ElevationData::ValueType>::max() );
}

USUL_IMPLEMENT_IUNKNOWN_MEMBERS ( ElevationData, ElevationData::BaseClass );


///////////////////////////////////////////////////////////////////////////////
//
//  Constructor.
//
///////////////////////////////////////////////////////////////////////////////

ElevationData::ElevationData ( SizeType width, SizeType height ) : BaseClass(),
  _width ( width ),
  _height ( height ),
  _data ( width * height, 0.0 ),
  _noDataValue ( Detail::DEFAULT_NO_DATA_VALUE )
{
}


///////////////////////////////////////////////////////////////////////////////
//
//  Constructor.
//
///////////////////////////////////////////////////////////////////////////////

ElevationData::ElevationData ( SizeType width, SizeType height, const std::vector<ValueType>& data ) : BaseClass(),
  _width ( width ),
  _height ( height ),
  _data ( data ),
  _noDataValue ( Detail::DEFAULT_NO_DATA_VALUE )
{
}


///////////////////////////////////////////////////////////////////////////////
//
//  Destructor.
//
///////////////////////////////////////////////////////////////////////////////

ElevationData::~ElevationData()
{
}


///////////////////////////////////////////////////////////////////////////////
//
//  Query for interface.
//
///////////////////////////////////////////////////////////////////////////////

Usul::Interfaces::IUnknown* ElevationData::queryInterface ( unsigned long iid )
{
  switch ( iid )
  {
  case Usul::Interfaces::IUnknown::IID:
  case Minerva::Common::IElevationData::IID:
    return static_cast<Minerva::Common::IElevationData*> ( this );
  default:
    return 0x0;
  }
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the value at a given row and column.
//
///////////////////////////////////////////////////////////////////////////////

void ElevationData::value ( SizeType row, SizeType column, ValueType value )
{
  _data.at ( this->_index ( row, column ) ) = value;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the value at a given row and column.
//
///////////////////////////////////////////////////////////////////////////////

ElevationData::ValueType ElevationData::value ( SizeType row, SizeType column ) const
{
  return _data.at ( this->_index ( row, column ) );
}


///////////////////////////////////////////////////////////////////////////////
//
//  Set the no data value.
//
///////////////////////////////////////////////////////////////////////////////

void ElevationData::noDataValue ( ValueType noData )
{
  _noDataValue = noData;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the no data value.
//
///////////////////////////////////////////////////////////////////////////////

ElevationData::ValueType ElevationData::noDataValue() const
{
  return _noDataValue;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the width.
//
///////////////////////////////////////////////////////////////////////////////

ElevationData::SizeType ElevationData::width() const
{
  return _width;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the height.
//
///////////////////////////////////////////////////////////////////////////////

ElevationData::SizeType ElevationData::height() const
{
  return _height;
}


///////////////////////////////////////////////////////////////////////////////
//
//  Get the index for the row and column.
//
///////////////////////////////////////////////////////////////////////////////

ElevationData::SizeType ElevationData::_index ( SizeType row, SizeType column ) const
{
  return ( row * _height ) + column;
}
